﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using System.Diagnostics;
using Newtonsoft.Json;

namespace MySoftWareList
{
    /*
     * update 2022年4月14日10:50:34
     * 程序启动首先尝试读取本地配置文件，如果有则进行解析并填充
     * 
     * 可以通过reload和save来将当前配置进行保存
     * 
     * 可以通过git对文件列表进行更新和上传
     * 
     */

    public class SingleSoftwareInformatino
    {
        public string Name { get; set; }
        public string Describe { get; set; }
        public string Website { get; set; }
        public string DownloadAddress { get; set; }
        public SingleSoftwareInformatino()
        {
            Name = "";
            Describe = "";
            Website = "";
            DownloadAddress = "";
        }
    }
    public class ConfigInfo
    {
        public string SyncAddress { get; set; }
        public List<SingleSoftwareInformatino> SoftwareList { get; set; }
        public ConfigInfo()
        {
            SyncAddress = "";
            SoftwareList = new List<SingleSoftwareInformatino>();
        }
    }
    class CommonTools
    {
        public string GetCurrentFolder()
        {
            //获取当前目录，用于执行其他命令之后切回初始位置
            string ret = "";
            ret = System.IO.Directory.GetCurrentDirectory();
            return ret;
        }
        public void SwitchFolder(string folder)
        {
            //用于切换到特定目录
            if(System.IO.Directory.Exists(folder))
            {
                System.IO.Directory.SetCurrentDirectory(folder);
            }
            
        }
        public List<string> GetFileContentToList(string filename)
        {
            List<string> ret = new List<string>();
            //有可能文件不存在或者读取错误
            if (!System.IO.File.Exists(filename))
            {
                FileStream fstream = new FileStream(filename, FileMode.OpenOrCreate);
                fstream.Close();
            }
            try
            {
                StreamReader sr = new StreamReader(filename, Encoding.Default);
                string? line;
                while ((line = sr.ReadLine()) != null)
                {
                    if (line != "")
                    {
                        ret.Add(line);
                    }
                }
                sr.Close();
            }
            catch (Exception e)
            {

            }

            return ret;

        }

        public string GetFileContent(string filename)
        {
            string ret = "";
            //有可能文件不存在或者读取错误
            if (!System.IO.File.Exists(filename))
            {
                FileStream fstream = new FileStream(filename, FileMode.OpenOrCreate);
                fstream.Close();
            }
            try
            {
                StreamReader sr = new StreamReader(filename, Encoding.UTF8);
                string? line;
                line = sr.ReadLine();
                while (line != null)
                {
                    ret += line;
                    line = sr.ReadLine();
                }
                sr.Close();
            }
            catch (Exception e)
            {

            }

            return ret;

        }

        public void WriteToFile(string filename, string message,Encoding? encode=null,bool Append=false)
        {
            
            if(encode is null)
            {
                encode= Encoding.UTF8; 
            }
            using (System.IO.StreamWriter file = new System.IO.StreamWriter(filename, Append, encode))
            {
                file.Write(message);
                file.Close();
            }
        }

        public void CopyFile(string file_src,string file_dst)
        {
            if(System.IO.File.Exists(file_src))
            {
                System.IO.File.Copy(file_src, file_dst, true);
            }
            
        }
        public string getFolderFromAddress(string gitaddress)
        {
            string ret = "";
            //https://gitee.com/youdias/MySoftwareList.git
            int index = gitaddress.LastIndexOf('/');
            do
            {
                if (index is -1)
                {
                    break;
                }
                string gitName = gitaddress.Substring(index + 1);
                if (gitName.Length < 4)
                {
                    break;
                }
                string folderName = gitName.Substring(0, gitName.Length - 4);
                ret = folderName;
            } while (false);

            return ret;
        }

    }

    class GitHelper
    {
        public string GetCurrentFolder()
        {
            //获取当前目录，用于执行其他命令之后切回初始位置
            string ret = "";
            ret = System.IO.Directory.GetCurrentDirectory();
            return ret;
        }
        public void SwitchFolder(string folder)
        {
            //用于切换到特定目录
            System.IO.Directory.SetCurrentDirectory(folder);
        }

        CommonTools ct = new CommonTools();
        string getFolderFromAddress(string gitaddress)
        {
            string ret = "";
            //https://gitee.com/youdias/MySoftwareList.git
            int index = gitaddress.LastIndexOf('/');
            do
            {
                if (index is -1)
                {
                    break;
                }
                string gitName = gitaddress.Substring(index + 1);
                if (gitName.Length < 4)
                {
                    break;
                }
                string folderName = gitName.Substring(0, gitName.Length - 4);
                ret = folderName;
            } while (false);

            return ret;
        }

        //通过执行git命令将git内容更新到本地或者将本地内容上传到git
        string m_gitfolder = "";
        public void Pull(string gitaddress)
        {
            //执行pull命令，如果没有仓库怎执行git clone命令
            //首先从git中获取目录
            string gitFolderName = getFolderFromAddress(gitaddress);
            //判断当前目录是否存在
            string currentFolder = GetCurrentFolder();
            string targetFolder = currentFolder + "\\" + gitFolderName;
            m_gitfolder = targetFolder;
            if (System.IO.Directory.Exists(targetFolder) is false)
            {
                //ExecGitCommand("git clone " + gitaddress);
                ExecGitBat("gitclone.bat", gitaddress);
            }
            string folder = ct.GetCurrentFolder();
            ExecGitBat("gitpull.bat", folder + " " + targetFolder);
            //将当前内容上传到git，自动add  commit，commit内容固定为update
            //ct.SwitchFolder(targetFolder);
            //ExecGitCommand("git pull");
            //ct.SwitchFolder(folder);

        }
        public void Push(string gitaddress)
        {
            string folder = ct.GetCurrentFolder();
            //将当前内容上传到git，自动add  commit，commit内容固定为update

            string gitFolderName = getFolderFromAddress(gitaddress);
            //判断当前目录是否存在
            string currentFolder = GetCurrentFolder();
            string targetFolder = currentFolder + "\\" + gitFolderName;
            if (System.IO.Directory.Exists(targetFolder) is false)
            {
                ExecGitBat("gitclone.bat", gitaddress);
            }     
            ExecGitBat("gitupdate.bat", folder + " " + targetFolder);
        }
        void ExecGitCommand(string gitcmd)
        {
            //执行git命令
            Process proc = new Process();
            proc.StartInfo.CreateNoWindow = true;
            proc.StartInfo.FileName = "cmd.exe";
            proc.StartInfo.UseShellExecute = false;
            proc.StartInfo.RedirectStandardError = true;
            proc.StartInfo.RedirectStandardInput = true;
            proc.StartInfo.RedirectStandardOutput = true;
            proc.Start();
            //string output = proc.StandardError.ReadToEnd();
            proc.StandardInput.WriteLine(gitcmd+"\n");
            //proc.WaitForExit();
            proc.WaitForExitAsync();
            //proc.WaitForExit(5000);
            proc.Close();
        }

        void ExecGitBat(string batname,string args)
        {
            Process? proc = null;
            try
            {
                proc = new Process();
                proc.StartInfo.FileName = batname;
                proc.StartInfo.Arguments = args;
                proc.StartInfo.CreateNoWindow = true;
#if DEBUG
                proc.StartInfo.CreateNoWindow = false;
#endif
                
                proc.Start();
                proc.WaitForExit();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception Occurred :{0},{1}", ex.Message, ex.StackTrace.ToString());
            }
        }
    }

    public class Worker
    {
        //存放当前配置信息
        public ConfigInfo m_cfgInfo = new ConfigInfo();
        string configFileName = "MySoftwareList.json";

        public string GetGitAddress()
        {
            return m_cfgInfo.SyncAddress;
        }
        public List<SingleSoftwareInformatino> GetSoftwareInfoList()
        {
            return m_cfgInfo.SoftwareList;
        }


        //提供一些通用工具函数
        CommonTools ct = new CommonTools();

        //用于辅助执行git命令
        GitHelper gitHelper = new GitHelper();
        public void Test()
        {
            {
                //public void RunCmd(string cmd)
                //{
                //    Process proc = null;
                //    proc.StartInfo.CreateNoWindow = true;
                //    proc.StartInfo.FileName = "cmd.exe";
                //    proc.StartInfo.UseShellExecute = false;
                //    proc.StartInfo.RedirectStandardError = true;
                //    proc.StartInfo.RedirectStandardInput = true;
                //    proc.StartInfo.RedirectStandardOutput = true;
                //    proc.Start();
                //    proc.StandardInput.WriteLine(cmd);
                //    proc.Close();
                //}
                Process proc = new Process();
                proc.StartInfo.CreateNoWindow = true;
                proc.StartInfo.FileName = "cmd.exe";
                proc.StartInfo.UseShellExecute = false;
                proc.StartInfo.RedirectStandardError = true;
                proc.StartInfo.RedirectStandardInput = true;
                proc.StartInfo.RedirectStandardOutput = true;
                proc.Start();
                proc.StandardInput.WriteLine("git clone https://gitee.com/youdias/MySoftwareList.git ");
                proc.Close();
            }
            //进行各种测试
            //gitHelper.Init("git", @"F:\home\vs2022\Csharp\MySoftWareList\bin\Debug\net6.0-windows\MySoftwareList");
            gitHelper.Pull("https://gitee.com/youdias/MySoftwareList.git");
        }

        //添加或者更新git
        string m_gitAddress = "";
        public void DownloadGit(string address)
        {
            m_gitAddress = address;
            gitHelper.Pull(address);
        }

        //将最新配置更新到git服务器上
        public void UploadGit(string address)
        {
            gitHelper.Push(address);
        }

        public string GetConfig()
        {
            string ret = "";
            string folder = ct.GetCurrentFolder();
            string filepath = folder + "\\" + configFileName;
            string content = ct.GetFileContent(filepath);
            if (content != "")
            {
#pragma warning disable CS8601 // 引用类型赋值可能为 null。
                m_cfgInfo = JsonConvert.DeserializeObject<ConfigInfo>(content);
#pragma warning restore CS8601 // 引用类型赋值可能为 null。
            }

            return ret;
        }
        public void SaveConfig(string content)
        {
            string folder = ct.GetCurrentFolder();
            string filepath = folder + "\\" + configFileName;
            ct.WriteToFile(filepath, content);
        }
        public void SyncFileFromGit2Local()
        {
            if (m_cfgInfo.SyncAddress == "")
            {
                if (m_gitAddress == "")
                {
                    return;
                }
                else
                {
                    m_cfgInfo.SyncAddress = m_gitAddress;
                }

            }
            string folder = ct.GetCurrentFolder();
            string localfile = folder + "\\" + configFileName;
             //将当前内容上传到git，自动add  commit，commit内容固定为update
            string gitFolderName = ct.getFolderFromAddress(m_cfgInfo.SyncAddress);
            //判断当前目录是否存在         
            string gitFile = folder + "\\" + gitFolderName+"\\"+configFileName;
            ct.CopyFile(gitFile, localfile);
        }
        
        public void SyncFileFromLocal2Git()
        {
            if (m_cfgInfo.SyncAddress == "")
            {
                if(m_gitAddress=="")
                {
                    return;
                }
                else
                {
                    m_cfgInfo.SyncAddress = m_gitAddress;
                }
                
            }
            string folder = ct.GetCurrentFolder();
            string localfile = folder + "\\" + configFileName;
            //将当前内容上传到git，自动add  commit，commit内容固定为update
            string gitFolderName = ct.getFolderFromAddress(m_cfgInfo.SyncAddress);
            //判断当前目录是否存在         
            string gitFile = folder + "\\" + gitFolderName + "\\" + configFileName;

            ct.CopyFile(localfile, gitFile);
        }
    }
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        Worker wk = new Worker();

        string m_syncaddress = "";
        List<SingleSoftwareInformatino> m_softwaeList = new List<SingleSoftwareInformatino>();
        public MainWindow()
        {
            InitializeComponent();
            Init();
        }

        void PrepareBat()
        {
            CommonTools ct = new CommonTools();
            string folder = ct.GetCurrentFolder()+"\\";
            string localfilename = folder + "gitpull.bat";
            string content = "";
            if (!System.IO.File.Exists(localfilename))
            {
                content = "cd %2\ngit pull\ngit checkout .\ncd % 1";
                ct.WriteToFile(localfilename, content,Encoding.ASCII);
            }
            localfilename = folder + "gitclone.bat";
            if (!System.IO.File.Exists(localfilename))
            {
                content = "git clone %1";
                ct.WriteToFile(localfilename, content, Encoding.ASCII);
            }
            localfilename = folder + "gitupdate.bat";
            if (!System.IO.File.Exists(localfilename))
            {
                content = "cd %2\ngit add .\ngit commit -m \"update\"\ngit push\ncd %1\n";
                ct.WriteToFile(localfilename, content, Encoding.ASCII);
            }
        }
        public void Init()
        {
            PrepareBat();
            //wk.Test();
            //同步文件
            
            wk.SyncFileFromGit2Local();

            //初始化配置内容
            wk.GetConfig();
            m_syncaddress = wk.GetGitAddress();
            m_softwaeList = wk.GetSoftwareInfoList();
            if(m_syncaddress!="")
            {
                text_gitAddress.Text = m_syncaddress;
            }            
            datagrid_sofwtareList.ItemsSource = null;
            datagrid_sofwtareList.ItemsSource = m_softwaeList;

        }
        private void btn_download_Click(object sender, RoutedEventArgs e)
        {
            //通过git更新
            string gitaddress = text_gitAddress.Text;
            wk.DownloadGit(gitaddress);

        }

        private void btn_upload_Click(object sender, RoutedEventArgs e)
        {
            //通过git上传
            m_syncaddress = text_gitAddress.Text;
            wk.SyncFileFromLocal2Git();
            wk.UploadGit(m_syncaddress);
        }

        private void btn_reload_Click(object sender, RoutedEventArgs e)
        {
            //重新读取文件
            Init();
        }

        private void btn_save_Click(object sender, RoutedEventArgs e)
        {
            //当前配置保存到文件            
            m_syncaddress = text_gitAddress.Text;
            wk.m_cfgInfo.SyncAddress = m_syncaddress;
            wk.m_cfgInfo.SoftwareList = m_softwaeList;
            string contet = JsonConvert.SerializeObject(wk.m_cfgInfo,Formatting.Indented);
            wk.SaveConfig(contet);
        }

        private void btn_down_Click(object sender, RoutedEventArgs e)
        {
            //下载选中的文件
            //首先获取下载链接
            //然后指定存放位置和文件名
            //最后下载
            var selectedvalue = datagrid_sofwtareList.SelectedItems;
            foreach(var singlevalue in selectedvalue)
            {
                var tmpdata = singlevalue  as SingleSoftwareInformatino;
                string address = tmpdata.DownloadAddress;
                if(address=="" || address.Length<4 || address.Substring(0,4)!="http")
                {
                    continue;
                }
                System.Diagnostics.Process.Start("explorer.exe", address);
            }

            

        }

        private void btn_exit_Click(object sender, RoutedEventArgs e)
        {
            //推出程序
            Environment.Exit(0);
        }
    }
}
